/**
 * 	 Copyright (c) 2008, 2009 Lukas Zaruba
 * 
 *   This file is part of UniAnalyzer (Universal Analyzer).
 *
 *   UniAnalyzer is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   UniAnalyzer is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with UniAnalyzer. If not, see <http://www.gnu.org/licenses/>.
 */


package net.zarubsys.unianalyzer.exporter.binary;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OutputStream;

import net.zarubsys.unianalyzer.dataminers.lpt.results.IResult;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IExportWizard;
import org.eclipse.ui.IWorkbench;

/**
 * BinaryExportWizard
 *
 * @author  &lt;A HREF=&quot;mailto:lukas.zaruba@gmail.com&quot;&gt;Lukas Zaruba&lt;/A&gt
 * @version $Revision$ $Date$
 */
public class BinaryExportWizard extends Wizard implements IExportWizard {
	
	private IStructuredSelection selection;
	private OutputSelectionPage outputSelection;
	private IWorkbench workbench;
	
	private static final Logger log = Logger.getLogger(BinaryExportWizard.class); 

	@Override
	public boolean performFinish() {
		try {
			finishInternal();
			return true;
		} catch (IllegalArgumentException e) {
			IStatus s = new Status(IStatus.ERROR, "net.zarubsys.unianalyzer.exporter.binary", e.getMessage());
			ErrorDialog ed = new ErrorDialog(workbench.getActiveWorkbenchWindow().getShell(), "Error exporting the file",
					"An error occured while exporting file.", s, IStatus.ERROR);
			ed.open();
			return false;
		}
	}

	private void finishInternal() throws IllegalArgumentException {
		if (selection.size() != 1) {
			throw new IllegalArgumentException("Exactly one file has to be selected!");
		}
		Object elem = selection.getFirstElement();
		if (!(elem instanceof IFile)) {
			throw new IllegalArgumentException("Selection has to be an instance of IFile!");
		}
		IFile inputIFile = (IFile) elem;
		String path = Platform.getInstanceLocation().getURL().getPath() + inputIFile.getFullPath().toString().substring(1);
		File inputFile = new File(path);
		ObjectInputStream ois = null;
		IResult result;
		try {
			ois = new ObjectInputStream(new FileInputStream(inputFile));
			result = (IResult) ois.readObject();
		} catch (FileNotFoundException e) {
			log.error("Error opening input file \"" + path + "\"", e);
			throw new IllegalArgumentException("Error opening input file \"" + path + "\"");
		} catch (IOException e) {
			log.error("IOExcpetion reading input file \"" + path + "\"", e);
			throw new IllegalArgumentException("IOExcpetion reading input file \"" + path + "\"");
		} catch (ClassNotFoundException e) {
			log.error("ClassNotFoundException while deserializing input file \"" + path + "\"", e);
			throw new IllegalArgumentException("Only lpt measuring results (*.lpt) can be exported!");
		} finally {
			try {
				if (ois != null) {
					ois.close();
				}	
			} catch (IOException e) {
				log.error("Error closing the input stream while deserializing input file \"" + path + "\"", e);
				throw new IllegalArgumentException("Internal exception while reading input file \"" + path + "\"");
			}
		}
		File outputFile = new File(outputSelection.getPath());
		OutputStream os = null;
		try {
			os = new BufferedOutputStream(new FileOutputStream(outputFile));
		} catch (FileNotFoundException e) {
			log.error("Error initializing output file \"" + outputFile.getAbsolutePath() + "\"", e);
			throw new IllegalArgumentException("Error writing to file \"" + outputFile.getAbsolutePath() + "\"");
		}
		try {
			for (int i = 0; i < result.getSamplesCount(); i++) {
				os.write(result.getContentAtPosition(i));
			}
		} catch (IOException e) {
			log.error("Error writing into the output file \"" + outputFile.getAbsolutePath() + "\"", e);
			throw new IllegalArgumentException("Error writing to file \"" + outputFile.getAbsolutePath() + "\"");
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				log.error("Error closing output stream on file \"" + outputFile.getPath() + "\"", e);
				throw new IllegalArgumentException("Error writing to file \"" + outputFile.getAbsolutePath() + "\"");
			}
		}
	}

	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this.selection = selection;
		this.workbench = workbench;
	}
	
	@Override
	public void addPages() {
		super.addPages();
		outputSelection = new OutputSelectionPage("Select destination");
		outputSelection.setDescription("Please select where you want to store data...");
		addPage(outputSelection);
	}

}


/*
 * $Log$
 */